package com.shire.shire_interface.service.friend.impl;

import com.shire.shire_interface.common.utils.StrUtils;
import com.shire.shire_interface.constants.Constants;
import com.shire.shire_interface.constants.WxConstants;
import com.shire.shire_interface.dao.friend.WxFriendDao;
import com.shire.shire_interface.model.friend.WxFriend;
import com.shire.shire_interface.model.friend.WxFriendExample;
import com.shire.shire_interface.model.friend.WxFriendLog;
import com.shire.shire_interface.model.user.WxAccount;
import com.shire.shire_interface.service.chat.WxChatService;
import com.shire.shire_interface.service.friend.WxFriendLogService;
import com.shire.shire_interface.service.friend.WxFriendService;
import com.shire.shire_interface.service.marketing.WxNewResponseService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 作者:  sll
 * 时间:  2019/7/25 14:29
 */
@Service
public class WxFriendServiceImpl implements WxFriendService {

    @Resource
    private WxFriendDao wxFriendDao;

    @Resource
    private WxFriendLogService wxFriendLogService;

    @Resource
    private WxNewResponseService newResponseService;

    @Resource
    private WxChatService wxChatService;

    @Override
    public List<WxFriend> getAllFriends(WxFriendExample example) {

        return wxFriendDao.selectByExample(example);
    }

    @Override
    public WxFriend getFriendByWxId(Integer csId, String wxAccount, String friendWxid) {
        WxFriendExample example = new WxFriendExample();
        example.createCriteria().andWxaccountEqualTo(wxAccount).andFriendwxidEqualTo(friendWxid);
        example.or().andWxaccountEqualTo(wxAccount).andFriendaliasEqualTo(friendWxid);;
        List<WxFriend> wxFriendList = wxFriendDao.selectByExample(example);

        WxFriend wxFriend = null;
        if (wxFriendList.size() > 0)
            wxFriend = wxFriendList.get(0);
        return wxFriend;
    }

    @Override
    public WxFriend getFrientById(Integer friendId) {
        return wxFriendDao.selectByPrimaryKey(friendId);
    }

    public void syncFriendsIncrement(List<Map<String, Object>> reqList, WxAccount account) {
        String wxAccount = account.getWxid();
        if (StrUtils.isBlank(wxAccount)) return;
        synchronized (wxAccount.intern()) {
            List<WxFriend> updateFriend = new ArrayList<>();
            for (Map<String, Object> reqMap : reqList) {
                String wxId = (String) reqMap.get("wxId");
                if (!checkValidWxId(wxId)) {
                    continue;
                }
                String nick = (String) reqMap.get("nick");
                Integer sex = StrUtils.getIntValue(String.valueOf(reqMap.get("sex")), null);
                String avatar = (String) reqMap.get("avatar");
                String alias = (String) reqMap.get("alias");
                String signature = (String) reqMap.get("signature");
                Integer isBrand = 0;
                if(reqMap.containsKey("isBrand"))
                    isBrand =  (boolean)reqMap.get("isBrand") ? 1 : 0;
                Integer isEnt = 0;
                if (reqMap.containsKey("isEnt"))
                    isEnt = (boolean)reqMap.get("isEnt") ? 1 : 0;
                Integer friendScene = (Integer) reqMap.get("friendScene");

                Integer isMyContact = 1;
                if(reqMap.containsKey("isMyContact"))
                    isMyContact = (Integer) reqMap.get("isMyContact");

//                if (isMyContact != 1)
//                    continue;
                WxFriend friend = getFriendByWxId(account.getCsid(), wxAccount, wxId);
                if (friend == null) {
                    friend = new WxFriend();
                    friend.setFriendwxid(wxId);
                    friend.setWxaccount(wxAccount);
                    friend.setFriendalias(alias);
                    friend.setCreatetime(new Date());
                    friend.setStatus(Constants.CommonStatus.ENABLE.ordinal());
                    friend.setIsmycontact(2);
                }
                boolean checkResponse = isMyContact == 1 && (friend.getId() == null || (isMyContact == 1 && friend.getIsmycontact() != 1));

                friend.setCsid(account.getCsid());
                friend.setStatus(Constants.CommonStatus.ENABLE.ordinal());
                friend.setFriendnick(nick);
                friend.setFriendsignature(signature);
                friend.setFriendsex(sex);
                friend.setUpdatetime(new Date());
                friend.setIsbrand(isBrand);
                friend.setIsent(isEnt);
                friend.setFriendscene(friendScene);
                friend.setIsmycontact(isMyContact);
                // 设置头像
                if (StrUtils.isNotBlank(avatar)) {
                    friend.setAvatar(avatar);
                }
                if (friend.getId() == null) {
                    friend.setCsid(account.getCsid());
                    wxFriendDao.insertSelective(friend);
                } else {
//                    wxFriendDao.updateByPrimaryKey(friend);
                    updateFriend.add(friend);
                }

                // 新增好有，从日志中查找csId
//                    WxFriendLog friendLog = wxFriendLogService.getFriendLog(wxAccount, friend.getFriendWxId());
                WxFriendLog friendLog = wxFriendLogService.getFriendLogByWxId(account.getCsid(), account.getWxid(), friend.getFriendwxid());

                if (friendLog != null ) {
                    friend.setFromgroupid(friendLog.getGroupid());
                    if (friendLog.getRststatus() != null && friendLog.getRststatus() != Constants.YesNo.YES.ordinal()) {
                        friendLog.setRststatus(Constants.YesNo.YES.ordinal());
                        friendLog.setUpdatetime(new Date());
                    }
                    friendLog.setFriendnick(friend.getFriendnick());
                    friendLog.setFriendavatar(friend.getAvatar());
                    friendLog.setFriendwxid(friend.getFriendwxid());
                    friendLog.setAddresult(isMyContact);
                    wxFriendLogService.updateFriendLog(account, friendLog);
                }else {
                    insertFriendLog(account, friend, isMyContact);
                }

                if (checkResponse){
                    newResponseService.checkNewResponse(account, friend);
                }
            }
            if (updateFriend.size()>0)
                wxFriendDao.batchUpdateByPrimaryKeySelective(updateFriend);
        }
    }

    @Override
    public Long getFriendCountByCsIdAndAccount(WxFriendExample friendExample) {
        return wxFriendDao.countByExample(friendExample);
    }

    @Override
    public List<WxFriend> selectByExample(WxFriendExample example) {
        return wxFriendDao.selectByExample(example);
    }


    @Override
    public Integer updateByPrimaryKeySelective(WxFriend wxFriend) {

        return wxFriendDao.updateByPrimaryKeySelective(wxFriend);
    }

    @Override
    public Integer updateByExampleSelective(WxFriend friend, WxFriendExample friendExample) {
        return wxFriendDao.updateByExampleSelective(friend,friendExample);
    }


    private boolean checkValidWxId(String wxId) {
        if (StrUtils.isBlank(wxId)) {
            return false;
        }
        return !wxId.equalsIgnoreCase("null") && !wxId.equalsIgnoreCase("(null)") && !wxId.equalsIgnoreCase("linkedinplugin");
    }

    public Map<String, WxFriend> getFriendsMap(WxAccount account){
        WxFriendExample friendExample = new WxFriendExample();
        friendExample.createCriteria().andWxaccountEqualTo(account.getWxid());
        List<WxFriend> list = wxFriendDao.selectByExample(friendExample);
        Map<String, WxFriend> map = new HashMap<>();
        for(WxFriend wxFriend : list){
            map.put(StrUtils.getNullStr(wxFriend.getFriendwxid(), wxFriend.getFriendnick()), wxFriend);
        }
        return map;
    }


    public void syncFriends(String type, List<Map<String, Object>> reqList, WxAccount account) {
        if (type.equalsIgnoreCase("whole")) {
            syncFriendsWhole(reqList, account);
        } else if (type.equalsIgnoreCase("increment")) {
            syncFriendsIncrement(reqList, account);
        } else if (type.equalsIgnoreCase("remove")) {
            syncFriendsRemove(reqList, account);
        }
    }



    public void syncFriendsWhole(List<Map<String, Object>> reqList, WxAccount account) {
        String wxAccount = account.getWxid();
        if (StrUtils.isBlank(wxAccount)) return;
        synchronized (wxAccount.intern()) {
            Map<String, WxFriend> oldMap = getFriendsMap(account);
            List<WxFriend> updateFriend = new ArrayList<>();
            for (Map<String, Object> reqMap : reqList) {
                String wxId = (String) reqMap.get("wxId");
                if (!checkValidWxId(wxId)) {
                    continue;
                }
                String nick = (String) reqMap.get("nick");
                Integer sex = StrUtils.getIntValue(String.valueOf(reqMap.get("sex")), null);
                String avatar = (String) reqMap.get("avatar");
                String alias = (String) reqMap.get("alias");
                String signature = (String) reqMap.get("signature");
                Integer isBrand =  (boolean)reqMap.get("isBrand") ? 1 : 0;
                Integer isEnt = (boolean)reqMap.get("isEnt") ? 1 : 0;
                Integer friendScene = (Integer) reqMap.get("friendScene");
                Integer isMyContact = (Integer) reqMap.get("isMyContact");
                WxFriend friend = oldMap.get(StrUtils.getNullStr(wxId));
//                if (isMyContact != 1){
//                    continue;
//                }
                if (friend == null) {
                    friend = new WxFriend();
                    friend.setFriendwxid(wxId);
                    friend.setFriendnick(nick);
                    friend.setWxaccount(wxAccount);
                    friend.setFriendalias(alias);
                    friend.setStatus(Constants.CommonStatus.ENABLE.ordinal());
                    friend.setIsmycontact(2);
                    friend.setCreatetime(new Date());
                } else {
                    oldMap.remove(wxId);
                }
                boolean checkResponse = isMyContact == 1 &&(friend.getId() == null || (isMyContact == 1 && friend.getIsmycontact() != 1));

                friend.setCsid(account.getCsid());
                friend.setFriendnick(nick);
                friend.setFriendsignature(signature);
                friend.setFriendsex(sex);
                friend.setUpdatetime(new Date());
                friend.setIsbrand(isBrand);
                friend.setIsent(isEnt);
                friend.setFriendscene(friendScene);
                friend.setIsmycontact(isMyContact);
                // 设置头像
                if (StrUtils.isNotBlank(avatar)) {
                    friend.setAvatar(avatar);
                }
                if (friend.getId() == null) {

                    if (friend.getCsid() == null) {
                        friend.setCsid(account.getCsid());
                    }
                    wxFriendDao.insert(friend);
                } else {
//                    wxFriendDao.updateByPrimaryKey(friend);
                    updateFriend.add(friend);
                }

                // 新增好有，从日志中查找csId
//                    WxFriendLog friendLog = wxFriendLogService.getFriendLog(wxAccount, friend.getFriendWxId());
                WxFriendLog friendLog = wxFriendLogService.getFriendLogByWxId(account.getCsid(), account.getWxid(), friend.getFriendwxid());
                boolean isNew = isMyContact == 1 && (friend.getIsmycontact() != isMyContact);
                if (friendLog != null ) {

                    friend.setFromgroupid(friendLog.getGroupid());
                    if (friendLog.getRststatus() != null && friendLog.getRststatus() != Constants.YesNo.YES.ordinal()) {
                        friendLog.setRststatus(Constants.YesNo.YES.ordinal());
                        friendLog.setUpdatetime(new Date());

                    }
                    friendLog.setFriendnick(friend.getFriendnick());
                    friendLog.setFriendavatar(friend.getAvatar());
                    friendLog.setAddresult(isMyContact);
                    friendLog.setFriendwxid(friend.getFriendwxid());
                    wxFriendLogService.updateFriendLog(account, friendLog);
                }else {
                    insertFriendLog(account, friend, isMyContact);
                }
                if (checkResponse){
                    newResponseService.checkNewResponse(account, friend);
                }
            }
            if (updateFriend.size()>0)
                wxFriendDao.batchUpdateByPrimaryKeySelective(updateFriend);
            // 删除未同步的好友
            for (Map.Entry<String, WxFriend> entry : oldMap.entrySet()) {
                wxFriendDao.deleteByPrimaryKey(entry.getValue().getId());
            }
        }
    }

    private void insertFriendLog(WxAccount account, WxFriend friend, int isMyContact) {
        WxFriendLog friendLog;
        friendLog = new WxFriendLog();
        if (isMyContact == 1)
            friendLog.setAddresult(1);
        else
            friendLog.setAddresult(0);
        friendLog.setCsid(account.getCsid());
        friendLog.setWxaccount(account.getWxid());
        if (friend.getFriendscene() < 99)
            friendLog.setAddtype(WxConstants.FriendAddType.FROMSEARCH.getCode());
        else
            friendLog.setAddtype(WxConstants.FriendAddType.ADDED.getCode());
        friendLog.setFriendnick(friend.getFriendnick());
        friendLog.setFriendwxid(friend.getFriendwxid());
        friendLog.setCreatetime(new Date());
        friendLog.setFriendnick(friend.getFriendnick());
        friendLog.setFriendavatar(friend.getAvatar());
        wxFriendLogService.inserFriendLog(friendLog);
    }

    private void syncFriendsRemove(List<Map<String, Object>> reqList, WxAccount account){
        String wxAccount = account.getWxid();
        if(StrUtils.isBlank(wxAccount)) return;
        synchronized (wxAccount.intern()) {
            for (Map<String, Object> reqMap : reqList) {
                String wxId = (String) reqMap.get("wxId");
                if (StrUtils.isBlank(wxId)) continue;

                WxFriend wxFriend = getFriendByWxId(account.getCsid(), wxAccount, wxId);
                if (wxFriend != null) {
                    wxFriendDao.deleteByPrimaryKey(wxFriend.getId());
                }
            }
        }
    }
}
